use std::{collections::HashMap, sync::Arc};

use monitor::{CompleterSuggestion, Monitor, MonitorCommand};

use super::mon_command_completer;
use crate::{dfs_read, DfsResult};

struct CatCommand;

impl CatCommand {
    fn do_cat(&self, args: &HashMap<String, String>) -> DfsResult<String> {
        let file = args.get("file").unwrap();

        let mut buf = String::new();
        dfs_read(file, &mut buf)?;
        Ok(buf)
    }
}

impl MonitorCommand for CatCommand {
    fn mon_protocol_exec(&self, args: &monitor::Protocol) -> DfsResult<monitor::Protocol> {
        let buf = self.do_cat(args)?;
        let mut hash = HashMap::new();
        hash.insert("file".to_string(), buf);
        Ok(hash)
    }

    fn mon_readline_arg_type(&self) -> Option<&'static str> {
        Some("file:*")
    }

    fn mon_readline_completer(&self, args: &[&str], is_space: bool) -> Option<CompleterSuggestion> {
        mon_command_completer(args.last(), false, is_space)
    }

    fn mon_readline_exec(
        &self,
        args: &HashMap<String, String>,
        printer: &monitor::MonitorPrinter,
    ) -> DfsResult<()> {
        let buf = self.do_cat(args)?;
        printer.print(buf);
        Ok(())
    }

    fn mon_readline_help(&self) -> String {
        String::from("将文件输出到监视器输出中")
    }

    fn mon_readline_long_help(&self) -> Option<String> {
        Some(String::from("用法: cat <文件>"))
    }
}

pub(crate) fn monitor_command_cat_register(mon: &Monitor) {
    mon.register_command("cat", Arc::new(CatCommand)).unwrap();
}
